package it.uniroma2.art.owlart.sesame2impl.models;

import it.uniroma2.art.owlart.exceptions.ModelAccessException;
import it.uniroma2.art.owlart.exceptions.ModelCreationException;
import it.uniroma2.art.owlart.exceptions.UnsupportedQueryLanguageException;
import it.uniroma2.art.owlart.models.TripleQueryModelHTTPConnection;
import it.uniroma2.art.owlart.query.BooleanQuery;
import it.uniroma2.art.owlart.query.GraphQuery;
import it.uniroma2.art.owlart.query.MalformedQueryException;
import it.uniroma2.art.owlart.query.Query;
import it.uniroma2.art.owlart.query.QueryLanguage;
import it.uniroma2.art.owlart.query.TupleQuery;
import it.uniroma2.art.owlart.query.Update;
import it.uniroma2.art.owlart.sesame2impl.query.BooleanQuerySesame2Impl;
import it.uniroma2.art.owlart.sesame2impl.query.GraphQuerySesame2Impl;
import it.uniroma2.art.owlart.sesame2impl.query.QueryLanguageConverter;
import it.uniroma2.art.owlart.sesame2impl.query.TupleQuerySesame2Impl;
import it.uniroma2.art.owlart.sesame2impl.query.UpdateSesame2Impl;

import org.openrdf.repository.RepositoryConnection;
import org.openrdf.repository.RepositoryException;
import org.openrdf.repository.http.HTTPRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class TripleQueryModelHTTPConnectionSesame2Impl implements TripleQueryModelHTTPConnection {

	protected static Logger logger = LoggerFactory.getLogger(TripleQueryModelHTTPConnectionSesame2Impl.class);

	protected HTTPRepository localrepository;
	// protected SailConnection conn;
	protected RepositoryConnection repConn;

	public TripleQueryModelHTTPConnectionSesame2Impl(String endpointURL) throws ModelCreationException {
		localrepository = new HTTPRepository(endpointURL, "");
		try {
			localrepository.initialize();
			repConn = localrepository.getConnection();
		} catch (RepositoryException e) {
			throw new ModelCreationException(e);
		}
	}

	public void disconnect() throws ModelAccessException {
		try {
			repConn.close();
		} catch (RepositoryException e) {
			throw new ModelAccessException(e);
		}
	}
	
	
	public Query createQuery(QueryLanguage ql, String query, String baseURI)
			throws UnsupportedQueryLanguageException, ModelAccessException, MalformedQueryException {
		try {
			org.openrdf.query.Query ses2query = repConn.prepareQuery(QueryLanguageConverter.convert(ql),
					query, baseURI);
			if (ses2query instanceof org.openrdf.query.TupleQuery) {
				return new TupleQuerySesame2Impl((org.openrdf.query.TupleQuery) ses2query);
			} else if (ses2query instanceof org.openrdf.query.BooleanQuery)
				return new BooleanQuerySesame2Impl((org.openrdf.query.BooleanQuery) ses2query);
			else if (ses2query instanceof org.openrdf.query.GraphQuery)
				return new GraphQuerySesame2Impl((org.openrdf.query.GraphQuery) ses2query);
			else
				throw new ModelAccessException("unknown query type");
		} catch (RepositoryException e) {
			throw new ModelAccessException(e);
		} catch (org.openrdf.query.MalformedQueryException e) {
			logger.error("malformed query");
			throw new MalformedQueryException(e);
		}
	}

	public BooleanQuery createBooleanQuery(QueryLanguage ql, String query, String baseURI)
			throws UnsupportedQueryLanguageException, ModelAccessException, MalformedQueryException {
		try {
			return new BooleanQuerySesame2Impl(repConn.prepareBooleanQuery(
					QueryLanguageConverter.convert(ql), query, baseURI));
		} catch (RepositoryException e) {
			throw new ModelAccessException(e);
		} catch (org.openrdf.query.MalformedQueryException e) {
			throw new MalformedQueryException(e);
		}
	}

	public GraphQuery createGraphQuery(QueryLanguage ql, String query, String baseURI)
			throws UnsupportedQueryLanguageException, ModelAccessException, MalformedQueryException {
		try {
			return new GraphQuerySesame2Impl(repConn.prepareGraphQuery(QueryLanguageConverter.convert(ql),
					query, baseURI));
		} catch (RepositoryException e) {
			throw new ModelAccessException(e);
		} catch (org.openrdf.query.MalformedQueryException e) {
			throw new MalformedQueryException(e);
		}
	}

	public TupleQuery createTupleQuery(QueryLanguage ql, String query, String baseURI)
			throws UnsupportedQueryLanguageException, ModelAccessException, MalformedQueryException {
		try {
			return new TupleQuerySesame2Impl(repConn.prepareTupleQuery(QueryLanguageConverter.convert(ql),
					query, baseURI));
		} catch (RepositoryException e) {
			throw new ModelAccessException(e);
		} catch (org.openrdf.query.MalformedQueryException e) {
			throw new MalformedQueryException(e);
		}
	}

	public Update createUpdate(QueryLanguage ql, String query, String baseURI)
			throws UnsupportedQueryLanguageException, ModelAccessException, MalformedQueryException {
		try {
			return new UpdateSesame2Impl(repConn.prepareUpdate(QueryLanguageConverter.convert(ql),
					query, baseURI));
		} catch (RepositoryException e) {
			throw new ModelAccessException(e);
		} catch (org.openrdf.query.MalformedQueryException e) {
			throw new MalformedQueryException(e);
		}
	}

}
